﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Scheduling.Models.Helpers;
using Scheduling.Models;
using Scheduling.Models.Interfaces;


namespace Scheduling.Controllers
{
    public class BookingRequestController : BaseController
    {
        [HttpGet]
        [Restrict(Roles = "Bookers")]
        public ActionResult Add()
        {
            ViewData["UserID"] = UserHelper.GetAuthenticatedUserID();
            return View();
        }

        [HttpPost]
        [Restrict(Roles = "Bookers")]
        public ActionResult Add(FormCollection form)
        {
            // Ev. todo: dela upp denna funktion i flera småfunktioner

            ViewData["UserID"] = UserHelper.GetAuthenticatedUserID();

            // Initialize stuff
            var instanceLoader = IoC.Resolve<ICourseInstanceLoader>();
            var roomLoader = IoC.Resolve<IRoomLoader>();
            var userLoader = IoC.Resolve<IUserLoader>();
            var bookingRequestLoader = IoC.Resolve<IBookingRequestLoader>();

            int value;
            string user = UserHelper.GetAuthenticatedUserID();

            foreach (string key in form.Keys)
                ViewData[key] = form.Get(key);

            BookingRequest result = new BookingRequest();
            result.AllowedDays = new Dictionary<DayOfWeek, DayType>();

            // Saves booker
            result.Booker = userLoader.GetUser(user);

            // Validates Course instance
            if(!int.TryParse(ViewData["inCourseInstanceID"].ToString(),out value))
                return View((object)"Invalid Course Instance");
            result.CourseInstance=instanceLoader.GetCourseInstance(value);
            result.Year = result.CourseInstance.Year;

            // Validates start period
            if (!int.TryParse(ViewData["inStartPeriod"].ToString(), out value) || (value > 5 || value <= 0))
                return View((object)"Invalid Period");
            result.StartPeriod = value;

            // Validates start time
            if(!int.TryParse(ViewData["inStartTime"].ToString().Split(':')[0],out value))
                return View((object)"Invalid start time");
            result.Time = value;

            // Validates days & day types
            DayType day;

            if (ViewData["inMonday"] != null && Enum.TryParse(ViewData["inMondayDayType"].ToString(), out day))
                result.AllowedDays.Add(DayOfWeek.Monday, day);
            if (ViewData["inTuesday"] != null && Enum.TryParse(ViewData["inTuesdayDayType"].ToString(), out day))
                result.AllowedDays.Add(DayOfWeek.Tuesday, day);
            if (ViewData["inWednesday"] != null && Enum.TryParse(ViewData["inWednesdayDayType"].ToString(), out day))
                result.AllowedDays.Add(DayOfWeek.Wednesday, day);
            if (ViewData["inThursday"] != null && Enum.TryParse(ViewData["inThursdayDayType"].ToString(), out day))
                result.AllowedDays.Add(DayOfWeek.Thursday, day);
            if (ViewData["inFriday"] != null && Enum.TryParse(ViewData["inFridayDayType"].ToString(), out day))
                result.AllowedDays.Add(DayOfWeek.Friday, day);

            if(result.AllowedDays.Count() == 0)
                return View((object)"No days chosen");

            // Validates lecture count
            if (!int.TryParse(ViewData["inLectureCount"].ToString(), out value) || value < 1)
                return View((object)"Invalid number of lectures");
            result.LectureCount = value;

            // Validates lecture length
            string time=ViewData["inLectureLength"].ToString();
            if (time!="2" && time !="4" && time!="6" && time!="8")
                return View((object)"Invalid lecture lenght");
            result.LectureLength = int.Parse(time);

            // Saves room pattern
            result.RoomPattern = ViewData["inRoomPattern"].ToString();

            // Validates room capacity
            if (!int.TryParse(ViewData["inRequiredCapacity"].ToString(), out value) || value < 1)
                return View((object)"Invalid RoomCapacity");
            result.RequiredCapacity = value;

            // Validates room type
            RoomType roomtype;
            if(!Enum.TryParse(ViewData["inRoomType"].ToString(),out roomtype))
                return View((object)"Invalid RoomType");

            // Validates priority
            Priority prio;
            if (!Enum.TryParse(ViewData["inPriority"].ToString(), out prio))
                return View((object)"Invalid priority");
            result.Priority = prio;

            bookingRequestLoader.InsertBookingRequest(result);

            return RedirectToAction("List");
        }

        [HttpGet]
        [Restrict(Roles = "Bookers")]
        public ActionResult List()
        {
            var requestloader = IoC.Resolve<IBookingRequestLoader>();

            string userID = UserHelper.GetAuthenticatedUserID();
            List<BookingRequest> result = requestloader.GetBookingRequestsByUserId(userID);

            if (result == null)
                result = new List<BookingRequest>();

            return View(result);
        }

        [HttpGet]
        [Restrict (Roles = "Administrators")]
        public ActionResult ListAll()
        {
            var requestloader = IoC.Resolve<IBookingRequestLoader>();
            List<BookingRequest> result = requestloader.GetBookingRequests();

            if (result == null)
                result = new List<BookingRequest>();

            return View(result);
        }



        public ActionResult Show(int id)
        {
            var bookingRequestLoader = IoC.Resolve<IBookingRequestLoader>();

            var bookingRequest = bookingRequestLoader.GetBookingRequest(id);

            if (bookingRequest == null)
                FileNotFound();

            return View(bookingRequest);
        }

        [Restrict(Roles = "Administrators")]
        public ActionResult Delete(string Id)
        {
            var requestLoader = IoC.Resolve<IBookingRequestLoader>();
            int value;
            if(int.TryParse(Id,out value))
                requestLoader.DeleteRequest(value);
          return RedirectToAction("List");
        }

        [Restrict(Roles = "Administrators")]
        public ActionResult Process()
        {
            MultipleBooker mb = new MultipleBooker();
            mb.GenerateBookings(null, 0, 0);
            var tran = mb.GenerateTransaction();
            return RedirectToAction("List");
        }
    }
}
